package com.lh.glassmuseum.service;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lh.glassmuseum.config.AppConfig;
import com.lh.glassmuseum.config.SerialPortConfig;
import com.lh.glassmuseum.util.AuthResult;
import com.lh.glassmuseum.util.GlassResult;
import com.lh.glassmuseum.util.UrlSignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

public class HttpService {
    public static HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(15))
            .version(HttpClient.Version.HTTP_2)
            .build();
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpService.class);

    public static void sendHttpRequest(String text) {
        Map<String, String> params = new HashMap<>(7,1);
        String timestamp = String.valueOf(System.currentTimeMillis());
        String nonce = UrlSignUtil.getCurrTime()+UrlSignUtil.buildRandom(4);
        params.put("chanType","1");
        params.put("chanCode", SerialPortService.config.getChanCode());
        params.put("codeType","1");
        params.put("code",text.trim());
        params.put("appId", AppConfig.appId);
        params.put("timestamp", timestamp);
        params.put("nonce",nonce);
        Map<String,String> jsonObject = new HashMap<>();
        jsonObject.put("appId",AppConfig.appId);
        jsonObject.put("timestamp",timestamp);
        jsonObject.put("nonce",nonce);
        jsonObject.put("sign",UrlSignUtil.paramSign(params,AppConfig.token));
        String xSign;
        try {
            xSign = UrlSignUtil.encode(JSON.toJSONString(jsonObject),AppConfig.aesKey);
        } catch (Exception e) {
            LOGGER.error("发送请求失败：签名失败:",e);
            TipService.updateDisplay("发送请求失败：签名失败");
            InputService.input.clear();
            return;
        }
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(String.format(AppConfig.url,text.trim(),SerialPortService.config.getChanCode())))
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .header("X-AUTH-SIGN", xSign)
                .POST(HttpRequest.BodyPublishers.ofString("{}"))
                .build();
        GlassResult result;
        try {
            HttpResponse<String> rep = client.send(request, HttpResponse.BodyHandlers.ofString());
            result = JSONObject.parseObject(rep.body(),GlassResult.class);
        } catch (IOException | InterruptedException e) {
            LOGGER.error("发送请求失败：",e);
            TipService.updateDisplay("发送请求失败：请求异常");
            InputService.input.clear();
            return;
        }
        if(result.isSuccess()){
            if(SerialPortService.sendSerialCommand()){
                MediaService.playPass();
                ImageService.setOkImg();
                TipService.updateDisplay("请通行");
            }else{
                MediaService.playError();
                ImageService.setErrorImg();
                TipService.updateDisplay("开闸失败");
            }
        }else{
            //替换logo
            ImageService.setErrorImg();
            //播报
            MediaService.playStop();
            TipService.updateDisplay(result.getMessage());
        }
        //清空输入内容
        InputService.input.clear();
    }

    public static boolean checkToken(){
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(AppConfig.checkUrl+SerialPortService.config.getToken()))
                .GET()
                .build();
        AuthResult result;
        try {
            HttpResponse<String> rep = client.send(request, HttpResponse.BodyHandlers.ofString());
            result = JSONObject.parseObject(rep.body(),AuthResult.class);
        } catch (Exception e) {
            LOGGER.error("发送心跳请求失败：",e);
            return false;
        }
        return result.isOk();
    }

}
